﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;

namespace RRD2.Controler
{
    public class Processor
    {
        DAL.Logger logger = new DAL.Logger();
        DAL.Database database = new DAL.Database();

        private Model.Lorry lorry = new Model.Lorry();
        private ShipmentStatus _shipmentStatus = new ShipmentStatus() { Status = Model.ShipmentStatus.Close, TruckNumber=string.Empty};
        private DateTime _openedLorryTime;

        public ShipmentStatus ShipmentStatus
        {
            get { return _shipmentStatus; }
            set { _shipmentStatus = value; }
        }

        public DateTime OpenedLorryTime
        {
            get { return _openedLorryTime; }
            set { _openedLorryTime = value; }
        }
        
        public Model.Lorry Lorry
        {
            get { return lorry; }
            private set { lorry = value; }
        }
        
        public RRD2.Model.Statement GetScan(string _barcode)
        {
            RRD2.Model.Statement statement = new RRD2.Model.Statement();
            
            try
            {
                var barcode = CheckBarcode(_barcode);

                if (!barcode.Value.Equals(Model.BarcodeType.Error))
                {
                    statement = Process(barcode);
                }
                else
                {
                    statement.Value = ConfigurationManager.AppSettings["WrongBarcode"];
                    statement.Type = Model.StatementType.Error;
                }
                logger.WriteLog(statement, _barcode);
                if (!statement.Type.Equals(Model.StatementType.Message))
                {
                    Controler.Messanger.PlaySound();
                }
                statement.Barcode.Value = _barcode;
            }
            catch (Exception ex)
            {
                DAL.Logger.WriteException(ex);
            }
            return statement;
        }
        
        private Model.Statement Process(Model.Barcode _barcode)
        {
            var statement = new Model.Statement();
            statement.Barcode = _barcode;
            try
            {
                var status = ShipmentStatus.Status;

                if (status.Equals(Model.ShipmentStatus.Close)) //status aplikacji CLOSED
                {
                    if (_barcode.Type.Equals(Model.BarcodeType.Open)) // barcode OPEN-DOCK
                    {
                        ShipmentStatus.Status = Model.ShipmentStatus.ReadyToOpen;
                        statement.Value = ConfigurationManager.AppSettings["OpenDockConfirm"];
                        statement.Type = Model.StatementType.Message;
                        
                    }
                    else if(_barcode.Type.Equals(Model.BarcodeType.Exit)) // barcode EXIT
                    {
                        statement.Value = ConfigurationManager.AppSettings["ExitAppConfirm"];
                        statement.Type = Model.StatementType.Exit;
                    }                       
                    else
                    {
                        statement.Value = ConfigurationManager.AppSettings["OpenDockDeny"];
                        statement.Type = Model.StatementType.Error;
                    }
                }
                else if(status.Equals(Model.ShipmentStatus.ReadyToOpen)) // status aplikacji ReadyToOpen
                {
                    if (_barcode.Type.Equals(Model.BarcodeType.Lorry)) // barcode LORRY-NUMBER
                    {
                        try
                        {
                            ShipmentStatus.Status = Model.ShipmentStatus.Open;
                            statement.Value = ConfigurationManager.AppSettings["LorryNumberConfirm"];
                            OpenedLorryTime = DateTime.Now;
                            Lorry.LorryName = _barcode.Value;
                            Lorry.LorryId = database.SetLorryHeader(_barcode.Value);
                            statement.Type = Model.StatementType.Message;
                        }
                        catch (Exception ex)
                        {
                            DAL.Logger.WriteException(ex);
                        }
                    }
                    else if (_barcode.Type.Equals(Model.BarcodeType.Close)) // barcode CLOSE
                    {
                        ShipmentStatus.Status = Model.ShipmentStatus.Close;
                        statement.Value = ConfigurationManager.AppSettings["CloseDockConfirm"];
                        statement.Type = Model.StatementType.Message;
                        lorry = new Model.Lorry();
                    }
                    else
                    {
                        statement.Value = ConfigurationManager.AppSettings["LorryNumberDeny"];
                        statement.Type = Model.StatementType.Error;
                    }
                }
                else if(status.Equals(Model.ShipmentStatus.Open)) // status aplikacji Open
                {
                    if (_barcode.Type.Equals(Model.BarcodeType.Trolley)) // barcode TROLLEY NUMBER
                    {
                        if (database.TrolleyConfirm(_barcode.Value)) // Confirm barcode
                        {
                            if (database.SetLorryDetail(_barcode.Value, Lorry.LorryId))
                            {
                                statement.Type = Model.StatementType.Message;
                                statement.Value = ConfigurationManager.AppSettings["TrolleyNumberConfirm"];
                                statement.Barcode = _barcode;
                            }
                        }
                        else
                        {
                            statement.Type = Model.StatementType.Error;
                            statement.Value = ConfigurationManager.AppSettings["TrolleyNumberIncorrect"];
                            ShipmentStatus.Status = Model.ShipmentStatus.Blocked;
                        }
                    }
                    else if (_barcode.Type.Equals(Model.BarcodeType.Close)) // barcode CLOSE
                    {
                        database.UpdateLorryHeader(Lorry.LorryId);
                        statement.Type = Model.StatementType.Message;
                        statement.Value = ConfigurationManager.AppSettings["CloseDockConfirm"];
                        lorry = new Model.Lorry();
                        OpenedLorryTime = new DateTime();
                        ShipmentStatus.Status = Model.ShipmentStatus.Close;
                    }
                    else
                    {
                        statement.Value = ConfigurationManager.AppSettings["TrolleyNumberDeny"];
                        statement.Type = Model.StatementType.Error;
                    }
                }
                else if (status.Equals(Model.ShipmentStatus.Blocked)) // status aplikacji Blocked
                {
                    if (_barcode.Type.Equals(Model.BarcodeType.EmployeeId)) // barcode Employee Id
                    {
                        statement.Value = ConfigurationManager.AppSettings["EmployeeIdConfirm"];
                        statement.Type = Model.StatementType.Warning;
                        ShipmentStatus.Status = Model.ShipmentStatus.Open;
                    }
                    else
                    {
                        statement.Value = ConfigurationManager.AppSettings["EmployeeIdDeny"];
                        statement.Type = Model.StatementType.Error;
                    }
                }
            }
            catch (Exception ex)
            {
                DAL.Logger.WriteException(ex);
            }
            return statement;
        }

        private Model.Barcode CheckBarcode(string _barcode)
        {
            Model.Barcode barcode = new Model.Barcode();

            if(_barcode.Length.Equals(ConfigurationManager.AppSettings["OpenDock"].Length) &&
                _barcode.StartsWith(ConfigurationManager.AppSettings["OpenDock"].TrimEnd('x')))
            {
                barcode.Value = _barcode;
                barcode.Type = Model.BarcodeType.Open;
            }
            else if (_barcode.Length.Equals(ConfigurationManager.AppSettings["CloseDock"].Length) &&
                _barcode.StartsWith(ConfigurationManager.AppSettings["CloseDock"].TrimEnd('x')))
            {
                barcode.Value = _barcode;
                barcode.Type = Model.BarcodeType.Close;
                
            }
            else if (_barcode.Length.Equals(ConfigurationManager.AppSettings["Exit"].Length) &&
                _barcode.StartsWith(ConfigurationManager.AppSettings["Exit"].TrimEnd('x')))
            {
                barcode.Value = _barcode;
                barcode.Type = Model.BarcodeType.Exit;
            }
            else if (_barcode.Length.Equals(ConfigurationManager.AppSettings["LorryNumber"].Length) &&
                _barcode.StartsWith(ConfigurationManager.AppSettings["LorryNumber"].TrimEnd('x')))
            {
                barcode.Value = _barcode;
                barcode.Type = Model.BarcodeType.Lorry;                
            }
            else if (_barcode.Length.Equals(ConfigurationManager.AppSettings["TrolleyNumber"].Length) &&
                _barcode.StartsWith(ConfigurationManager.AppSettings["TrolleyNumber"].TrimEnd('x')))
            {
                barcode.Value = _barcode;
                barcode.Type = Model.BarcodeType.Trolley;
            }
            else if (_barcode.Length.Equals(ConfigurationManager.AppSettings["EmployeeIdNumber"].Length) &&
                _barcode.StartsWith(ConfigurationManager.AppSettings["EmployeeIdNumber"].TrimEnd('x')))
            {
                barcode.Value = _barcode;
                barcode.Type = Model.BarcodeType.EmployeeId;
            } 
            else
            {
                barcode.Value = _barcode;
                barcode.Type = Model.BarcodeType.Error;
            }
            return barcode;
        }
        
    }
}
